/**
 ******************************************************************************
 * @file           : bsp_adc.c
 * @brief          : ADC Driver Implementation (STM32F1xx)
 ******************************************************************************
 * @attention
 *
 * ADC驱动程序实现文件
 * 提供单通道、多通道、DMA采集等功能
 * 支持内部温度传感器和参考电压采集
 *
 ******************************************************************************
 */

/* Includes ------------------------------------------------------------------*/
#include "./BSP/ADC/bsp_adc.h"
#include "./BSP/ADC/bsp_adc_config.h"

/* Private includes ----------------------------------------------------------*/
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
static ADC_HandleTypeDef sg_adc_handle;                     /*!< ADC句柄 */
static DMA_HandleTypeDef sg_adc_dma_handle;                 /*!< DMA句柄 */
static uint16_t sg_adc_dma_buf[ADC_DMA_BUF_SIZE];           /*!< DMA缓冲区 */
static uint8_t sg_adc_initialized = 0;                      /*!< 初始化标志 */
static uint8_t sg_adc_dma_enabled = 0;                      /*!< DMA启用标志 */
static ADC_State_e sg_adc_state = ADC_STATE_IDLE;           /*!< ADC状态 */

/* ADC通道配置表 */
static const ADC_Channel_Config_t sg_adc_channel_config[ADC_CHANNEL_NUM] = ADC_CHANNEL_CONFIG_TABLE;

/* Private function prototypes -----------------------------------------------*/
static void adc_gpio_init(void);
static void adc_peripheral_init(void);
#if ADC_SUPPORT_DMA
static void adc_dma_peripheral_init(void);
#endif
#if ADC_FILTER_ENABLE
static uint16_t adc_filter(uint16_t new_value, uint8_t channel);
#endif

/* Private functions ---------------------------------------------------------*/

#if ADC_FILTER_ENABLE
/**
 * @brief       ADC数据一阶低通滤波函数
 * @details     对指定通道的ADC数据进行一阶低通滤波处理
 *              滤波公式：Y_new = α*X + (1-α)*Y_old
 *              使用浮点运算确保精度，自动管理各通道状态
 *
 * @param[in]   new_value 新的ADC采样值
 * @param[in]   channel 通道索引(0 ~ ADC_CHANNEL_NUM-1)
 *
 * @retval      滤波后的ADC值
 *
 * @note        每个通道首次调用时直接使用真实值初始化，避免从0开始滤波
 * @note        滤波系数α可在bsp_adc_config.h中配置
 * @note        各通道独立维护滤波状态，完全封装内部实现
 */
static uint16_t adc_filter(uint16_t new_value, uint8_t channel)
{
    /* 静态变量，保存各通道的滤波状态 */
    static uint16_t last_values[ADC_CHANNEL_NUM] = {0};          /* 上一次的滤波结果 */
    static uint8_t channel_initialized[ADC_CHANNEL_NUM] = {0};   /* 各通道初始化标志 */
    
    /* 检查通道号是否有效 */
    if (channel >= ADC_CHANNEL_NUM)
    {
        log_w("滤波器通道号无效: %d (最大: %d)", channel, ADC_CHANNEL_NUM - 1);
        return new_value; /* 通道号无效，直接返回原值 */
    }
    
    /* 检查当前通道是否已初始化 */
    if (!channel_initialized[channel])
    {
        /* 第一次调用该通道，直接使用当前值初始化 */
        last_values[channel] = new_value;
        channel_initialized[channel] = 1;
        return new_value;
    }
    
    /* 一阶低通滤波: y(n) = α·x(n) + (1-α)·y(n-1) */
    float filtered_value = ADC_FILTER_ALPHA * (float)new_value + (1.0f - ADC_FILTER_ALPHA) * (float)last_values[channel];
    
    /* 更新该通道的last_value */
    last_values[channel] = (uint16_t)filtered_value;
    
    return (uint16_t)filtered_value;
}
#endif

/**
 * @brief       ADC GPIO初始化
 *
 * @param       无
 *
 * @retval      无
 *
 * @note        根据配置表自动配置外部通道引脚为模拟输入
 * @note        内部通道（温度、VREF）不需要GPIO配置
 */
static void adc_gpio_init(void)
{
    GPIO_InitTypeDef gpio_init_struct;
    uint8_t gpio_ports_enabled = 0;  /* 记录已使能的端口（避免重复使能） */
    
    gpio_init_struct.Mode = GPIO_MODE_ANALOG;
    
    /* 遍历配置表，初始化所有外部通道 */
    for (uint8_t i = 0; i < ADC_CHANNEL_NUM; i++)
    {
        /* 只处理外部通道 */
        if (sg_adc_channel_config[i].type == ADC_CH_TYPE_EXTERNAL)
        {
            /* 使能GPIO时钟（避免重复使能同一端口） */
            if (sg_adc_channel_config[i].gpio_port == GPIOA && !(gpio_ports_enabled & 0x01))
            {
                __HAL_RCC_GPIOA_CLK_ENABLE();
                gpio_ports_enabled |= 0x01;
            }
            else if (sg_adc_channel_config[i].gpio_port == GPIOB && !(gpio_ports_enabled & 0x02))
            {
                __HAL_RCC_GPIOB_CLK_ENABLE();
                gpio_ports_enabled |= 0x02;
            }
            else if (sg_adc_channel_config[i].gpio_port == GPIOC && !(gpio_ports_enabled & 0x04))
            {
                __HAL_RCC_GPIOC_CLK_ENABLE();
                gpio_ports_enabled |= 0x04;
            }
            
            /* 配置GPIO为模拟输入 */
            gpio_init_struct.Pin = sg_adc_channel_config[i].gpio_pin;
            HAL_GPIO_Init(sg_adc_channel_config[i].gpio_port, &gpio_init_struct);
        }
    }
}

/**
 * @brief       ADC外设初始化
 *
 * @param       无
 *
 * @retval      无
 *
 * @note        配置ADC工作模式和参数
 */
static void adc_peripheral_init(void)
{
    /* 使能ADC时钟 */
    ADC_ADCx_CLK_ENABLE();

    /* 配置ADC参数 */
    sg_adc_handle.Instance = ADC_ADCx;
    sg_adc_handle.Init.DataAlign = ADC_DATAALIGN_RIGHT;             /* 右对齐 */
    sg_adc_handle.Init.ScanConvMode = ADC_SCAN_DISABLE;             /* 非扫描模式 */
    sg_adc_handle.Init.ContinuousConvMode = DISABLE;                /* 单次转换 */
    sg_adc_handle.Init.NbrOfConversion = 1;                         /* 1个转换通道 */
    sg_adc_handle.Init.DiscontinuousConvMode = DISABLE;             /* 禁止不连续采样 */
    sg_adc_handle.Init.NbrOfDiscConversion = 0;
    sg_adc_handle.Init.ExternalTrigConv = ADC_SOFTWARE_START;       /* 软件触发 */

    /* 初始化ADC */
    if (HAL_ADC_Init(&sg_adc_handle) != HAL_OK)
    {
        log_e("ADC外设初始化失败");
        return;
    }

    /* 校准ADC */
    if (HAL_ADCEx_Calibration_Start(&sg_adc_handle) != HAL_OK)
    {
        log_w("ADC校准失败");
    }
}

#if ADC_SUPPORT_DMA
/**
 * @brief       ADC DMA初始化
 *
 * @param       无
 *
 * @retval      无
 *
 * @note        配置DMA用于多通道连续采集
 * @note        DMA通道根据ADC_SELECT_NUM自动配置
 * @note        ADC2不支持DMA，此函数仅在ADC1/3时编译
 */
static void adc_dma_peripheral_init(void)
{
    /* 使能DMA时钟 */
    ADC_DMA_CLK_ENABLE();

    /* 配置DMA参数 */
    sg_adc_dma_handle.Instance = ADC_DMAx_CHANNELx;
    sg_adc_dma_handle.Init.Direction = DMA_PERIPH_TO_MEMORY;        /* 外设到内存 */
    sg_adc_dma_handle.Init.PeriphInc = DMA_PINC_DISABLE;            /* 外设地址不增 */
    sg_adc_dma_handle.Init.MemInc = DMA_MINC_ENABLE;                /* 内存地址递增 */
    sg_adc_dma_handle.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;  /* 外设16位 */
    sg_adc_dma_handle.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;     /* 内存16位 */
    sg_adc_dma_handle.Init.Mode = DMA_CIRCULAR;                     /* 循环模式 */
    sg_adc_dma_handle.Init.Priority = DMA_PRIORITY_HIGH;            /* 高优先级 */

    /* 初始化DMA */
    if (HAL_DMA_Init(&sg_adc_dma_handle) != HAL_OK)
    {
        log_e("ADC DMA初始化失败");
        return;
    }

    /* 关联DMA和ADC */
    __HAL_LINKDMA(&sg_adc_handle, DMA_Handle, sg_adc_dma_handle);

    /* 重新配置ADC为扫描模式 */
    sg_adc_handle.Init.ScanConvMode = ADC_SCAN_ENABLE;              /* 扫描模式 */
    sg_adc_handle.Init.ContinuousConvMode = ENABLE;                 /* 连续转换 */
    sg_adc_handle.Init.NbrOfConversion = ADC_CHANNEL_NUM;           /* 转换通道数 */

    if (HAL_ADC_Init(&sg_adc_handle) != HAL_OK)
    {
        log_e("ADC DMA模式配置失败");
        return;
    }

    /* 配置ADC通道（根据配置表自动配置） */
    ADC_ChannelConfTypeDef adc_ch_conf = {0};
    adc_ch_conf.SamplingTime = ADC_SAMPLE_TIME;
    
    /* Rank映射表（STM32 HAL库的Rank定义） */
    const uint32_t rank_table[16] = {
        ADC_REGULAR_RANK_1,  ADC_REGULAR_RANK_2,  ADC_REGULAR_RANK_3,  ADC_REGULAR_RANK_4,
        ADC_REGULAR_RANK_5,  ADC_REGULAR_RANK_6,  ADC_REGULAR_RANK_7,  ADC_REGULAR_RANK_8,
        ADC_REGULAR_RANK_9,  ADC_REGULAR_RANK_10, ADC_REGULAR_RANK_11, ADC_REGULAR_RANK_12,
        ADC_REGULAR_RANK_13, ADC_REGULAR_RANK_14, ADC_REGULAR_RANK_15, ADC_REGULAR_RANK_16
    };
    
    /* 遍历配置表，自动配置所有通道 */
    for (uint8_t i = 0; i < ADC_CHANNEL_NUM; i++)
    {
        adc_ch_conf.Channel = sg_adc_channel_config[i].channel;
        adc_ch_conf.Rank = rank_table[i];
        HAL_ADC_ConfigChannel(&sg_adc_handle, &adc_ch_conf);
    }
}
#endif /* ADC_SUPPORT_DMA */

/* Exported functions --------------------------------------------------------*/

/**
 * @brief       ADC初始化
 *
 * @param       无
 *
 * @retval      无
 *
 * @note        初始化ADC GPIO和外设，单次转换模式
 */
void adc_init(void)
{
    if (sg_adc_initialized)
    {
        log_w("ADC已经初始化");
        return;
    }

    /* 初始化GPIO */
    adc_gpio_init();

    /* 初始化ADC外设 */
    adc_peripheral_init();

    /* 设置状态 */
    sg_adc_state = ADC_STATE_IDLE;
    sg_adc_initialized = 1;

    log_i("ADC初始化完成（单次转换模式）");
}

/**
 * @brief       ADC反初始化
 *
 * @param       无
 *
 * @retval      无
 *
 * @note        释放ADC资源
 */
void adc_deinit(void)
{
    if (!sg_adc_initialized)
    {
        return;
    }

#if ADC_SUPPORT_DMA
    /* 停止DMA */
    if (sg_adc_dma_enabled)
    {
        adc_stop_dma();
    }
#endif

    /* 反初始化ADC */
    HAL_ADC_DeInit(&sg_adc_handle);

    /* 反初始化GPIO（根据配置表） */
    for (uint8_t i = 0; i < ADC_CHANNEL_NUM; i++)
    {
        if (sg_adc_channel_config[i].type == ADC_CH_TYPE_EXTERNAL)
        {
            HAL_GPIO_DeInit(sg_adc_channel_config[i].gpio_port, sg_adc_channel_config[i].gpio_pin);
        }
    }

    /* 清除标志 */
    sg_adc_initialized = 0;
    sg_adc_dma_enabled = 0;
    sg_adc_state = ADC_STATE_IDLE;

    log_i("ADC已反初始化");
}

/**
 * @brief       ADC DMA初始化
 *
 * @param       无
 *
 * @retval      无
 *
 * @note        初始化DMA用于多通道连续采集
 * @note        ADC2不支持DMA，调用此函数会报错
 */
void adc_dma_init(void)
{
#if !ADC_SUPPORT_DMA
    log_e("ADC2不支持DMA！请使用ADC1或ADC3");
    return;
#else
    if (!sg_adc_initialized)
    {
        log_e("请先调用adc_init()");
        return;
    }

    if (sg_adc_dma_enabled)
    {
        log_w("ADC DMA已经初始化");
        return;
    }

    /* 初始化DMA */
    adc_dma_peripheral_init();

    sg_adc_dma_enabled = 1;
    log_i("ADC DMA初始化完成（%d通道扫描模式）", ADC_CHANNEL_NUM);
#endif
}

/**
 * @brief       读取单个ADC通道
 *
 * @param[in]   channel ADC通道号
 *
 * @retval      ADC转换值(0-4095)
 *
 * @note        阻塞式单次转换
 */
uint16_t adc_read_channel(uint32_t channel)
{
    ADC_ChannelConfTypeDef adc_ch_conf = {0};
    uint16_t adc_value = 0;

    if (!sg_adc_initialized)
    {
        log_e("ADC未初始化");
        return 0;
    }

    sg_adc_state = ADC_STATE_CONVERTING;

    /* 配置通道 */
    adc_ch_conf.Channel = channel;
    adc_ch_conf.Rank = ADC_REGULAR_RANK_1;
    adc_ch_conf.SamplingTime = ADC_SAMPLE_TIME;

    if (HAL_ADC_ConfigChannel(&sg_adc_handle, &adc_ch_conf) != HAL_OK)
    {
        log_e("ADC通道配置失败");
        sg_adc_state = ADC_STATE_ERROR;
        return 0;
    }

    /* 启动转换 */
    HAL_ADC_Start(&sg_adc_handle);

    /* 等待转换完成 */
    if (HAL_ADC_PollForConversion(&sg_adc_handle, 100) == HAL_OK)
    {
        adc_value = (uint16_t)HAL_ADC_GetValue(&sg_adc_handle);
    }
    else
    {
        log_w("ADC转换超时");
        sg_adc_state = ADC_STATE_ERROR;
    }

    /* 停止转换 */
    HAL_ADC_Stop(&sg_adc_handle);

    sg_adc_state = ADC_STATE_IDLE;
    return adc_value;
}

/**
 * @brief       读取通道电压
 *
 * @param[in]   channel ADC通道号
 *
 * @retval      电压值(V)
 *
 * @note        转换为实际电压值
 */
float adc_read_voltage(uint32_t channel)
{
    uint16_t adc_value = adc_read_channel(channel);
    return (float)adc_value * ADC_VREF / ADC_MAX_VALUE;
}

/**
 * @brief       ADC多次采样平均
 *
 * @param[in]   channel ADC通道号
 * @param[in]   times   采样次数(1-255, 0会自动设为1)
 *
 * @retval      平均ADC值
 *
 * @note        多次采样求平均，提高稳定性
 * @note        建议采样次数：快速读取用10次，精确测量用20次
 */
uint16_t adc_read_average(uint32_t channel, uint8_t times)
{
    uint32_t sum = 0;
    uint8_t i;

    if (times == 0)
    {
        times = 1;
    }

    for (i = 0; i < times; i++)
    {
        sum += adc_read_channel(channel);
    }

    return (uint16_t)(sum / times);
}

/**
 * @brief       电压多次采样平均
 *
 * @param[in]   channel ADC通道号
 * @param[in]   times   采样次数
 *
 * @retval      平均电压值(V)
 *
 * @note        多次采样求平均电压
 */
float adc_read_voltage_average(uint32_t channel, uint8_t times)
{
    uint16_t adc_value = adc_read_average(channel, times);
    return (float)adc_value * ADC_VREF / ADC_MAX_VALUE;
}

#if ADC_SUPPORT_DMA
/**
 * @brief       启动DMA采集
 *
 * @param       无
 *
 * @retval      ADC_OK         启动成功
 * @retval      ADC_ERROR_PARAM DMA未初始化
 * @retval      ADC_ERROR_HAL   HAL库错误
 *
 * @note        启动多通道DMA连续采集
 * @note        ADC2不支持DMA，此函数仅在ADC1/3时编译
 */
ADC_Error_e adc_start_dma(void)
{
    if (!sg_adc_initialized)
    {
        log_e("ADC未初始化");
        return ADC_ERROR_PARAM;
    }

    if (!sg_adc_dma_enabled)
    {
        log_e("DMA未初始化，请先调用adc_dma_init()");
        return ADC_ERROR_PARAM;
    }

    sg_adc_state = ADC_STATE_DMA;

    /* 启动ADC DMA */
    if (HAL_ADC_Start_DMA(&sg_adc_handle, (uint32_t *)sg_adc_dma_buf, ADC_DMA_BUF_SIZE) != HAL_OK)
    {
        log_e("ADC DMA启动失败");
        sg_adc_state = ADC_STATE_ERROR;
        return ADC_ERROR_HAL;
    }

    log_i("ADC DMA采集已启动");
    return ADC_OK;
}

/**
 * @brief       停止DMA采集
 *
 * @param       无
 *
 * @retval      ADC_OK         停止成功
 * @retval      ADC_ERROR_HAL   HAL库错误
 *
 * @note        停止DMA连续采集
 * @note        ADC2不支持DMA，此函数仅在ADC1/3时编译
 */
ADC_Error_e adc_stop_dma(void)
{
    if (!sg_adc_initialized || !sg_adc_dma_enabled)
    {
        return ADC_ERROR_PARAM;
    }

    /* 停止ADC DMA */
    if (HAL_ADC_Stop_DMA(&sg_adc_handle) != HAL_OK)
    {
        log_e("ADC DMA停止失败");
        return ADC_ERROR_HAL;
    }

    sg_adc_state = ADC_STATE_IDLE;
    log_i("ADC DMA采集已停止");
    return ADC_OK;
}

/**
 * @brief       获取DMA采集值
 *
 * @param[in]   channel_index 通道索引(0 ~ ADC_CHANNEL_NUM-1)
 *
 * @retval      ADC平均值
 *
 * @note        从DMA缓冲区读取指定通道的平均值
 * @note        如果启用滤波（ADC_FILTER_ENABLE=1），返回值已经过一阶低通滤波
 * @note        ADC2不支持DMA，此函数仅在ADC1/3时编译
 */
uint16_t adc_get_dma_value(uint8_t channel_index)
{
    uint32_t sum = 0;
    uint16_t i;
    uint16_t sample_count = ADC_DMA_BUF_SIZE / ADC_CHANNEL_NUM;

    if (channel_index >= ADC_CHANNEL_NUM)
    {
        log_w("通道索引超出范围");
        return 0;
    }

    /* 计算该通道的平均值 */
    for (i = 0; i < sample_count; i++)
    {
        sum += sg_adc_dma_buf[i * ADC_CHANNEL_NUM + channel_index];
    }
    
    uint16_t average_value = (uint16_t)(sum / sample_count);

#if ADC_FILTER_ENABLE
    /* 对ADC数据进行滤波处理 */
    return adc_filter(average_value, channel_index);
#else
    return average_value;
#endif
}

/**
 * @brief       获取DMA采集电压
 *
 * @param[in]   channel_index 通道索引(0 ~ ADC_CHANNEL_NUM-1)
 *
 * @retval      电压值(V)
 *
 * @note        从DMA缓冲区读取电压
 * @note        ADC2不支持DMA，此函数仅在ADC1/3时编译
 */
float adc_get_dma_voltage(uint8_t channel_index)
{
    uint16_t adc_value = adc_get_dma_value(channel_index);
    return (float)adc_value * ADC_VREF / ADC_MAX_VALUE;
}
#endif /* ADC_SUPPORT_DMA */

/**
 * @brief       读取内部温度传感器
 *
 * @param       无
 *
 * @retval      温度值(℃)
 *
 * @note        使用内部温度传感器测量芯片温度
 */
float adc_read_temperature(void)
{
    float temp_voltage;
    float temperature;

    /* 读取温度传感器电压 */
    temp_voltage = adc_read_voltage_average(ADC_CHANNEL_TEMPSENSOR, ADC_AVERAGE_TIMES);

    /* 计算温度：T = (V25 - Vsense) / Avg_Slope + 25 */
    temperature = (ADC_TEMP_V25 - temp_voltage) / ADC_TEMP_AVG_SLOPE + 25.0f;

    log_d("芯片温度: %.2f℃", temperature);
    return temperature;
}

/**
 * @brief       读取内部参考电压
 *
 * @param       无
 *
 * @retval      参考电压值(V)
 *
 * @note        内部参考电压约1.2V
 */
float adc_read_vrefint(void)
{
    float vrefint = adc_read_voltage_average(ADC_CHANNEL_VREFINT, ADC_AVERAGE_TIMES);
    log_d("内部参考电压: %.3fV", vrefint);
    return vrefint;
}

/**
 * @brief       获取VDDA电压
 *
 * @param       无
 *
 * @retval      VDDA电压(V)
 *
 * @note        通过内部参考电压反推VDDA
 * @note        每次调用会进行多次采样求平均，适合偶尔调用
 */
float adc_get_vdda(void)
{
    uint16_t vrefint_adc = adc_read_average(ADC_CHANNEL_VREFINT, ADC_AVERAGE_TIMES);
    float vdda = 1.2f * ADC_MAX_VALUE / vrefint_adc;
    log_d("VDDA电压: %.3fV", vdda);
    return vdda;
}

/**
 * @brief       获取ADC当前状态
 *
 * @param       无
 *
 * @retval      ADC_State_e 当前状态
 *
 * @note        用于状态监控和调试
 */
ADC_State_e adc_get_state(void)
{
    return sg_adc_state;
}

#if ADC_SUPPORT_DMA
/**
 * @brief       检查DMA是否运行
 *
 * @param       无
 *
 * @retval      1 运行中
 * @retval      0 未运行
 *
 * @note        用于判断DMA采集状态
 * @note        ADC2不支持DMA，此函数仅在ADC1/3时编译
 */
uint8_t adc_is_dma_running(void)
{
    return (sg_adc_state == ADC_STATE_DMA);
}
#endif

/**
 * @brief       打印ADC当前状态（用于调试）
 *
 * @param       无
 *
 * @retval      无
 *
 * @note        显示初始化状态、当前状态等
 */
void adc_print_status(void)
{
    const char *state_str[] = {"IDLE", "BUSY", "CONVERTING", "DMA", "ERROR"};

    log_i("ADC当前状态:");
    log_i("  初始化状态: %s", sg_adc_initialized ? "已初始化" : "未初始化");
    log_i("  当前状态: %s", state_str[sg_adc_state]);
    log_i("  DMA状态: %s", sg_adc_dma_enabled ? "已启用" : "未启用");
    log_i("  通道数量: %d", ADC_CHANNEL_NUM);
    log_i("  分辨率: %d位", ADC_RESOLUTION);
    log_i("  参考电压: %.2fV", ADC_VREF);
}

/**
 * @brief       打印所有通道值（用于调试）
 *
 * @param       无
 *
 * @retval      无
 *
 * @note        根据配置表自动显示所有配置的通道
 */
void adc_print_all_channels(void)
{
    uint8_t i;
    
    log_i("=== ADC通道值 ===");
    log_i("通道数量: %d", ADC_CHANNEL_NUM);
    
    /* 遍历配置表显示所有通道 */
    for (i = 0; i < ADC_CHANNEL_NUM; i++)
    {
        if (sg_adc_channel_config[i].type == ADC_CH_TYPE_EXTERNAL)
        {
            /* 外部通道 */
            log_i("  通道%d(外部): %dmV", i, 
                  (uint16_t)(adc_read_voltage(sg_adc_channel_config[i].channel) * 1000));
        }
        else
        {
            /* 内部通道 */
            if (sg_adc_channel_config[i].channel == ADC_CHANNEL_TEMPSENSOR)
            {
                log_i("  通道%d(温度): %.2f℃", i, adc_read_temperature());
            }
            else if (sg_adc_channel_config[i].channel == ADC_CHANNEL_VREFINT)
            {
                log_i("  通道%d(VREF): %.3fV", i, adc_get_vdda());
            }
        }
    }
}
